import 'dart:io';
import 'dart:math';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_reorderable_grid_view/entities/order_update_entity.dart';
import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:pp_uikit/pp_asset_picker.dart';
import 'package:pp_uikit/pp_image_selector/pp_image_model.dart';
import 'package:pp_uikit/pp_network_image.dart';
import 'package:pp_uikit/pp_toast.dart';
import 'package:pp_uikit/pp_uikit_constants.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

/// 单个 item 点击的回调
/// [index] 点击位置处于当前列的位置
/// [model] 被点击位置的数据
typedef OnSelectImageModelInterceptor = bool Function(
    int index, PPImageModel model);

class PPImageSelectorController {
  _PPImageSelectorState? _selectorState;

  void openPicker() {
    _selectorState?.openPicker();
  }

  void bindState(_PPImageSelectorState imageSelectorState) {
    _selectorState = imageSelectorState;
  }

  List<PPImageModel> getImagesModel() {
    return _selectorState?._getImagesModel() ?? [];
  }
}

// ignore: must_be_immutable
class PPImageSelector extends StatefulWidget {
  List<PPImageModel>? imagesList;

  /// 最多可选个数
  int maxCount;

  /// 一行个数
  int rowCount;

  /// 列间距
  double rowSpacing;

  /// 行间距
  double columnSpacing;

  PPImageSelectorController? controller;

  bool showCoverWidget;

  /// 是否能拖拽，默认：不能
  bool draggable;

  bool allowCapture;

  /// 点击事件
  void Function(PPImageModel model)? onItemTap;

  /// 拦截器
  OnSelectImageModelInterceptor? onSelectImageModelInterceptor;

  /// 数据源变动事件
  void Function(List<PPImageModel> list)? onItemsChanged;

  /// 右上角删除按钮点击事件
  void Function(PPImageModel model)? onDeleteTap;

  /// 选择图片回来回调
  void Function(List<AssetEntity>? list)? onPickerResult;

  PPImageSelector(
      {this.imagesList,
      this.maxCount = 9,
      this.rowCount = 4,
      this.rowSpacing = 10.0,
      this.columnSpacing = 10.0,
      this.onItemTap,
      this.onDeleteTap,
      this.onItemsChanged,
      this.onSelectImageModelInterceptor,
      this.onPickerResult,
      this.controller,
      this.showCoverWidget = false,
      this.draggable = false,
      this.allowCapture = true,
      Key? key})
      : super(key: key ?? Key("${Random().nextInt(999999999)}")) {
    controller ??= PPImageSelectorController();
    var tmpImagesList = <PPImageModel>[];
    if (imagesList != null) {
      for (var element in imagesList!) {
        tmpImagesList.add(element);
      }
    }
    if (tmpImagesList.length < maxCount) {
      tmpImagesList.add(PPImageModel(isAdd: true));
    }

    imagesList = <PPImageModel>[];
    imagesList!.addAll(tmpImagesList);
  }

  @override
  State<PPImageSelector> createState() => _PPImageSelectorState();

  int _canSelectImageCount() {
    var length = imagesList!.length;
    for (var element in imagesList!) {
      if (element.isAdd) {
        length--;
      } else if (element.asset != null) {
        // 已从弹框选中的资源，需要减，因为有已选中的相关逻辑
        length--;
      }
    }
    return maxCount - length;
  }

  void _onDeleteTap(PPImageModel model) {
    if (onDeleteTap != null) {
      onDeleteTap!(model);
    }
    imagesList!.remove(model);
    if (onItemsChanged != null) {
      var list = _getImagesModel();
      onItemsChanged!(list);
    }
  }

  bool _isExist(String id) {
    for (var element in imagesList!) {
      if (element.asset?.id == id) {
        return true;
      }
    }
    return false;
  }

  void _setImages(List<AssetEntity>? result) async {
    if (result == null) {
      return;
    }

    if (imagesList!.isNotEmpty) {
      imagesList!.removeLast();
    }

    for (var item in result) {
      if (!_isExist(item.id)) {
        var file = await item.file;
        if (file != null) {
          var model = PPImageModel(url: file.path, asset: item);
          imagesList!.add(model);
        }
      }
    }
    if (imagesList!.length > _canSelectImageCount()) {
      // 删除最后一个（add icon的Model）
      var last = imagesList!.last;
      if (last.isAdd) {
        imagesList!.removeLast();
      }
    } else {
      imagesList!.add(PPImageModel(isAdd: true));
    }

    if (onItemsChanged != null) {
      var list = _getImagesModel();
      onItemsChanged!(list);
    }
  }

  List<PPImageModel> _getImagesModel() {
    var list = <PPImageModel>[];
    for (var element in imagesList!) {
      if (!element.isAdd) {
        list.add(element);
      }
    }
    return list;
  }
}

class _PPImageSelectorState extends State<PPImageSelector> {
  final _scrollController = ScrollController();
  final _gridViewKey = GlobalKey();
  var lockedIndices = <int>[];

  @override
  void initState() {
    super.initState();
    widget.controller?.bindState(this);
    _setupLockedIndices();
  }

  // 计算添加按钮位置，锁定不用拖动
  void _setupLockedIndices() {
    if (widget.draggable && widget.imagesList != null) {
      for (int i = 0; i < widget.imagesList!.length; i++) {
        var model = widget.imagesList![i];
        if (model.isAdd) {
          lockedIndices = [i];
          break;
        }
      }
    }
  }

  List<PPImageModel> _getImagesModel() {
    return widget._getImagesModel();
  }

  @override
  Widget build(BuildContext context) {
    var gridDelegate = SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: widget.rowCount,
      childAspectRatio: 1,
      mainAxisSpacing: 10,
      crossAxisSpacing: 10,
    );
    if (widget.draggable == false) {
      return GridView.builder(
        shrinkWrap: true,
        //自适应高度显示
        physics: const NeverScrollableScrollPhysics(),
        //取消滚动效果
        gridDelegate: gridDelegate,
        itemCount: widget.imagesList!.length,
        itemBuilder: (context, index) {
          var model = widget.imagesList![index];
          return GestureDetector(
            child: ImageSelectorItem(
              model: model,
              index: index,
              showCoverWidget: widget.showCoverWidget,
              onDeleteTap: widget._onDeleteTap,
            ),
            onTap: () async {
              _itemOnTap(model, index);
            },
          );
        },
      );
    }

    var generatedChildren =
        List<Widget>.generate(widget.imagesList!.length, (index) {
      var model = widget.imagesList![index];
      var random = Random().nextInt(999999999);
      return GestureDetector(
        key: Key("$random${widget.key.toString()}$index"),
        child: ImageSelectorItem(
          key: Key("${widget.key.toString()}$index"),
          model: model,
          index: index,
          showCoverWidget: widget.showCoverWidget,
          onDeleteTap: widget._onDeleteTap,
        ),
        onTap: () async {
          _itemOnTap(model, index);
        },
      );
    });

    return ReorderableBuilder(
      onReorder: (List<OrderUpdateEntity> orderUpdateEntities) {
        for (final orderUpdateEntity in orderUpdateEntities) {
          final fruit = widget.imagesList!.removeAt(orderUpdateEntity.oldIndex);
          widget.imagesList!.insert(orderUpdateEntity.newIndex, fruit);
        }

        if (widget.onItemsChanged != null) {
          var list = _getImagesModel();
          widget.onItemsChanged!(list);
        }
        // setState(() {});
      },
      lockedIndices: lockedIndices,
      scrollController: _scrollController,
      enableScrollingWhileDragging: false,
      builder: (children) {
        return GridView.builder(
          key: _gridViewKey,
          controller: _scrollController,
          itemCount: children.length,
          shrinkWrap: true,
          itemBuilder: (context, index) {
            return children[index];
          },
          gridDelegate: gridDelegate,
        );
      },
      children: generatedChildren,
    );
  }

  void _itemOnTap(PPImageModel model, int index) {
    // 拦截
    if (widget.onSelectImageModelInterceptor != null) {
      var flag = widget.onSelectImageModelInterceptor!(index, model);
      if (flag == true) {
        return;
      }
    }

    if (widget.onItemTap != null) {
      if (model.isAdd) {
        // widget.controller?.openPicker();
        openPicker();
      } else {
        widget.onItemTap!(model);
      }
    }
  }

  Future<bool> externalStorageIsGranted() async {
    if (Platform.isAndroid) {
      try {
        var info = await DeviceInfoPlugin().androidInfo;
        int androidVersion = info.version.sdkInt;
        if (androidVersion >= 30) {
          var isGranted =
              await Permission.manageExternalStorage.request().isGranted;
          if (!isGranted) {
            return false;
          }
        }
      } catch (e) {
        debugPrint("PPImageSelector externalStorageIsGranted error: $e");
      }
    }
    return true;
  }

  void openPicker() async {
    var isGranted = await externalStorageIsGranted();
    if (!isGranted) {
      PPToast.show("请授权权限");
      return;
    }

    List<AssetEntity>? selectedAssets = <AssetEntity>[];
    for (var element in widget.imagesList!) {
      if (element.asset != null) {
        selectedAssets.add(element.asset!);
      }
    }
    final List<AssetEntity>? result = await PPAssetPicker.show(
      context,
      selectedAssets: selectedAssets,
      allowCapture: widget.allowCapture,
      maxAssets: widget._canSelectImageCount(),
    );
    if (mounted) {
      setState(() {
        widget._setImages(result);
      });
    }
    if (widget.onPickerResult != null) {
      widget.onPickerResult!(result);
    }
  }
}

// ignore: must_be_immutable
class ImageSelectorItem extends StatelessWidget {
  PPImageModel model;
  int index;
  bool showCoverWidget;

  /// 右上角删除按钮点击事件
  void Function(PPImageModel model)? onDeleteTap;
  ImageSelectorItem(
      {required this.model,
      required this.index,
      required this.showCoverWidget,
      this.onDeleteTap,
      Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        SizedBox(
          width: double.infinity,
          height: double.infinity,
          child: ClipRRect(
            borderRadius: BorderRadius.circular(5),
            child: _imageWidget(model, context),
          ),
        ),
        Offstage(
          offstage: !(showCoverWidget && !model.isAdd && index == 0),
          child: Align(
            alignment: Alignment.topLeft,
            child: Container(
              width: 36,
              height: 24,
              decoration: const BoxDecoration(
                color: Color(0x80000000),
                shape: BoxShape.rectangle,
                borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(4),
                    bottomRight: Radius.circular(4)),
              ),
              child: const Center(
                child: Text(
                  "封面",
                  style: TextStyle(
                    color: Color(0xFFFFFFFF),
                    fontSize: 12,
                  ),
                ),
              ),
            ),
          ),
        ),
        Offstage(
          offstage: model.isAdd,
          child: Align(
            alignment: Alignment.topRight,
            child: GestureDetector(
              onTap: () {
                if (onDeleteTap != null) {
                  onDeleteTap!(model);
                }
              },
              child: Image.asset(
                "images/icon_close_gray.png",
                fit: BoxFit.cover,
                width: 20,
                height: 20,
                package: PPUIKitConstant.packageName,
              ),
            ),
          ),
        ),
        // 视频展示播放图标
        Offstage(
          offstage: !model.isVideoUrl,
          child: Align(
            alignment: Alignment.center,
            child: GestureDetector(
              onTap: () {
                //
              },
              child: Image.asset(
                "images/icon_video_play.png",
                fit: BoxFit.cover,
                width: 30,
                height: 30,
                package: PPUIKitConstant.packageName,
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget _imageWidget(PPImageModel model, BuildContext context) {
    if (model.isAdd) {
      return Image.asset(
        "images/icon_add_iamge.png",
        fit: BoxFit.cover,
        package: PPUIKitConstant.packageName,
      );
    } else {
      String url = model.url!;
      if (url.contains("http")) {
        return PPNetworkImage(
          imageUrl: url,
          radius: 8,
        );
      } else {
        return Image.file(File(url), fit: BoxFit.cover);
      }
    }
  }
}
